package com.web.exiaodao.remote.controller;

import com.web.exiaodao.business.constant.JConstant;
import com.web.webstart.base.util.shortmsg.YuntongxunSmsUtil;
import com.web.exiaodao.business.entity.User;
import com.web.exiaodao.business.repository.UserRepository;
import com.web.exiaodao.remote.service.ApiUserService;
import com.web.exiaodao.remote.vo.UserVo;
import com.web.webstart.base.constant.XaConstant;
import com.web.webstart.base.controller.BaseController;
import com.web.webstart.base.exception.BusinessException;
import com.web.webstart.base.util.ImageUtil;
import com.web.webstart.base.util.Validator;
import com.web.webstart.base.util.XaUtil;
import com.web.webstart.base.util.encryptDir.DesUtil;
import com.web.webstart.base.util.encryptDir.MD5Util;
import com.web.webstart.base.util.result.XaResult;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;

import static com.web.webstart.base.util.XaUtil.dealMobileStr;

/**
 * @author eason.zt
 * @version V1.0
 * @Title: ApiUserController.java
 * @Package com.web.exiaodao.remote.controller
 * @Description: 用户信息接口
 * @date 2015年3月23日 下午1:00:00
 */
@Api(value = "User", description = "用户接口", position = 0)
@Controller
@RequestMapping("/api/user")
public class ApiUserController extends BaseController {

    private static final Logger logger = Logger.getLogger(ApiPayWxPayController.class);

    private static String SESSION_KEY = "phoneAndode";//验证码
    private static String SESSION_IMAGE_KEY = "phoneAndImagacode";//图像验证码
    private static String PATH_IMAGECode = "/upload/graphValidateCode";//图像验证码 存放目录

    @Autowired
    private ApiUserService userService;
    @Autowired
    UserRepository userRepository;

    /**
     * @param mobile
     * @param password
     * @return
     * @Title: register
     * @Description: 用户注册
     */
    @ApiOperation(value = "用户注册", notes = "用户注册,当返回的code=1时，注册成功后object返回对象", position = 1)
    @ResponseBody
    @RequestMapping(value = "register", method = RequestMethod.POST)
    public XaResult<UserVo> register(
            @ApiParam("手机号码,字段名:mobile") @RequestParam(value = "mobile") String mobile,
            @ApiParam("密码,字段名:password") @RequestParam(value = "password") String password,
            @ApiParam("验证码,字段名:code") @RequestParam String code,
            @ApiParam("图像验证码,字段名:imgCode,必填") @RequestParam(value = "imgCode") String imgCode,
            @ApiParam("图像路径,字段名:imgUrl,必填") @RequestParam(value = "imgUrl") String imgUrl,
            @ApiParam("推荐人手机号,字段名:recommendPhone") @RequestParam(value = "recommendPhone", required = false) String recommendPhone,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<UserVo> xr = new XaResult<>();
        if (XaUtil.isEmpty(mobile)) {
            xr.error("手机号码不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(password)) {
            xr.error("密码不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(code)) {
            xr.error("验证码不能为空");
            return xr;
        }
        //判断验证码是否正确
        if (!checkCode(request, mobile, code)) {
            xr.error("验证码不正确");
            return xr;
        }

        if (XaUtil.isEmpty(imgCode)) {
            xr.error("图像验证码不能为空！");
            return xr;
        }
        if (imgCode.trim().length() != 4) {
            xr.error("图像验证码格式有误！");
            return xr;
        }
        if (XaUtil.isEmpty(imgUrl)) {
            xr.error("图像路径不能为空！");
            return xr;
        }
        if (!imgUrl.endsWith(".JPEG")) {
            xr.error("图像路径格式不正确！");
            return xr;
        }
        //验证码图像验证码是否正确
        if (!checkImgCode(request, imgCode)) {
            xr.error("图像验证码不正确");
            return xr;
        }
        if (!Validator.isMobile(mobile)) {
            xr.error("手机号码格式不正确");
            return xr;
        }
        User user = userService.validMobile(mobile);
        if (XaUtil.isNotEmpty(user)) {
            xr.error("该手机号已注册");
            return xr;
        }

        //推荐人信息
        logger.info("推荐人手机号：|" + recommendPhone + "|");
        recommendPhone = XaUtil.isNotEmpty(recommendPhone) ? dealMobileStr(recommendPhone.trim()) : null;
        if (XaUtil.isNotEmpty(recommendPhone) && !Validator.isMobile(recommendPhone)) {
            xr.error("推荐人手机号码格式不正确");
            return xr;
        }

        User model = new User();
        model.setPassword(MD5Util.getMD5String(password));
        model.setMobile(mobile);
        model.setRecommendPhone(recommendPhone);
        return userService.createModel(model);
    }


//    测试 application/json 不要删除
//    $.ajax({
//        url: "http://192.168.0.101:8888/qinheyuan/api/user/login",
//                type: "POST",
//                dataType: "json",
//                contentType : "application/json",
//                data : JSON.stringify({mobile:'18049531390', password:'123456'}),
//        success : function(data){
//            console.log("success");
//            console.log(data);
//        },
//        error: function(e){
//            console.log("error");
//            console.log(e);
//        }
//    });

    /**
     * @return
     * @Title: login
     * @Description: 查询所有用户信息
     */
    @ApiOperation(value = "登录", notes = "登录,当返回的code=1时，登录成功，返回对象实体", position = 2)
    @ResponseBody
    //@RequestMapping(value = "login", method = RequestMethod.POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
    // @RequestParam @RequestBody @PathVariable 等参数绑定注解详解  http://blog.csdn.net/skh2015java/article/details/52757245
    //Spring MVC 学习笔记 json格式的输入和输出  http://www.cnblogs.com/crazy-fox/archive/2012/02/18/2357688.html  必须要加入对应的org.codehaus.jackson-->jackson-core-lgpl 库
    @RequestMapping(value = "login", method = RequestMethod.POST)
    public XaResult<UserVo> login(
            @ApiParam("{\"mobile\":\"18049531390\",\"password\":\"123456\"}") @RequestBody(required = false) UserVo.ApiLogin userVo,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws BusinessException {
        XaResult<UserVo> xr = new XaResult<>();
        String mobile = "";
        String password = "";
        String recommendPhone = "";
        if (userVo != null) {
            mobile = userVo.getMobile();
            password = userVo.getPassword();
        }

        try {
            Enumeration headerEnum = request.getHeaderNames();
            Cookie[] cookies = request.getCookies();
            //String requestBody = getBodyString(request.getReader());
            //logger.info(requestBody);//post application/json  才会放到request.getReader()
        } catch (Exception e) {
            e.printStackTrace();
        }

        String remortIP = getRemortIP(request);
        logger.info("登录用户的ip:" + remortIP);

        if (XaUtil.isEmpty(mobile)) {
            xr.error("手机号码不能为空");
            return xr;
        }
        if (!Validator.isMobile(mobile)) {
            xr.error("手机号码格式不正确");
            return xr;
        }
        if (XaUtil.isEmpty(password)) {
            xr.error("密码不能为空");
            return xr;
        }
        return userService.login(mobile, password);
    }

    /**
     * @return
     * @Title: 修改密码
     * @Description: 修改密码
     */
    @ApiOperation(value = "修改密码(登录)", notes = "修改密码,当返回的code=1时，保存成功后object返回对象", position = 3)
    @ResponseBody
    @RequestMapping(value = "pwdUpdate", method = RequestMethod.POST)
    public XaResult<UserVo> pwdUpdate(
            @ApiParam("用户id,字段名:id") @RequestParam(value = "id") Long id,
            @ApiParam("原密码(login给后台的全是明文密码；pay：给后台的全是md5后的密码),字段名:oldPassword") @RequestParam String oldPassword,
            @ApiParam("新密码,字段名:newPassword") @RequestParam String newPassword,
            @ApiParam("确认密码,字段名:confirmPassword") @RequestParam String confirmPassword,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<UserVo> xr = new XaResult<UserVo>();
        if (XaUtil.isEmpty(id)) {
            xr.error("id不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(oldPassword)) {
            xr.error("原密码不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(newPassword)) {
            xr.error("新密码不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(confirmPassword)) {
            xr.error("确认密码不能为空");
            return xr;
        }
        if (!newPassword.equals(confirmPassword)) {
            xr.error("新密码和确认密码不相符");
            return xr;
        }
        return userService.updatePwd(id, oldPassword, newPassword);
    }

    /**
     * @param mobile
     * @return
     * @Title: 忘记密码
     * @Description: 忘记密码
     */
    @ApiOperation(value = "忘记密码(登录)", notes = "忘记密码,当返回的code=1时，保存成功后object返回对象", position = 4)
    @ResponseBody
    @RequestMapping(value = "pwdForget", method = RequestMethod.POST)
    public XaResult<UserVo> pwdForget(
            @ApiParam("手机号,字段名:mobile") @RequestParam(value = "mobile") String mobile,
            @ApiParam("验证码,字段名:code") @RequestParam String code,
            @ApiParam("图像验证码,字段名:imgCode,必填") @RequestParam(value = "imgCode") String imgCode,
            @ApiParam("图像路径,字段名:imgUrl,必填") @RequestParam(value = "imgUrl") String imgUrl,
            @ApiParam("新密码,字段名:newPassword") @RequestParam String newPassword,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<UserVo> xr = new XaResult<UserVo>();
        if (XaUtil.isEmpty(mobile)) {
            xr.error("手机号码不能都为空！");
            return xr;
        }
        if (XaUtil.isNotEmpty(mobile)) {
            if (!Validator.isMobile(mobile)) {
                xr.error("手机号码格式不正确");
                return xr;
            }
        }
        if (XaUtil.isEmpty(code)) {
            xr.error("验证码不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(newPassword)) {
            xr.error("新密码不能为空");
            return xr;
        }
        //判断手机验证码是否正确
        if (XaUtil.isNotEmpty(mobile)) {
            if (!checkCode(request, mobile, code)) {
                xr.error("手机验证码不正确");
                return xr;
            }
        }

        if (XaUtil.isEmpty(imgCode)) {
            xr.error("图像验证码不能为空！");
            return xr;
        }
        if (imgCode.length() != 4) {
            xr.error("图像验证码格式有误！");
            return xr;
        }
        if (XaUtil.isEmpty(imgUrl)) {
            xr.error("图像路径不能为空！");
            return xr;
        }
        if (!imgUrl.endsWith(".JPEG")) {
            xr.error("图像路径格式不正确！");
            return xr;
        }
        //验证码图像验证码是否正确
        if (!checkImgCode(request, imgCode)) {
            xr.error("图像验证码不正确");
            return xr;
        }
        return userService.forgetPwd(mobile, newPassword);
    }

    /**
     * @return
     * @Title: 修改交易密码
     * @Description: 修改交易密码
     */
    @ApiOperation(value = "修改交易密码", notes = "修改密码,当返回的code=1时，保存成功后object返回对象", position = 3)
    @ResponseBody
    @RequestMapping(value = "payPwdUpdate", method = RequestMethod.POST)
    public XaResult<UserVo> payPwdUpdate(
            @ApiParam("用户id,字段名:id") @RequestParam(value = "id") Long id,
            @ApiParam("原密码(login给后台的全是明文密码；pay：给后台的全是md5后的密码),字段名:oldPassword") @RequestParam String oldPassword,
            @ApiParam("新密码,字段名:newPassword") @RequestParam String newPassword,
            @ApiParam("确认密码,字段名:confirmPassword") @RequestParam String confirmPassword,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<UserVo> xr = new XaResult<UserVo>();
        if (XaUtil.isEmpty(id)) {
            xr.error("id不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(oldPassword)) {
            xr.error("原密码不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(newPassword)) {
            xr.error("新密码不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(confirmPassword)) {
            xr.error("确认密码不能为空");
            return xr;
        }
        if (!newPassword.equals(confirmPassword)) {
            xr.error("新密码和确认密码不相符");
            return xr;
        }
        return userService.updatePayPwd(id, oldPassword, newPassword);
    }

    @ApiOperation(value = "设置交易密码", notes = "设置交易密码,当返回的code=1时，注册成功后object返回对象", position = 1)
    @ResponseBody
    @RequestMapping(value = "payPasswordSet", method = RequestMethod.POST)
    public XaResult<UserVo> payPasswordSet(
            @ApiParam("手机号,字段名:mobile") @RequestParam(value = "mobile") String mobile,
            @ApiParam("支付密码(login给后台的全是明文密码；pay：给后台的全是md5后的密码),字段名:payPassword") @RequestParam(value = "payPassword") String payPassword,
            @ApiParam("验证码,字段名:code") @RequestParam String code,
            @ApiParam("图像验证码,字段名:imgCode,必填") @RequestParam(value = "imgCode") String imgCode,
            @ApiParam("图像路径,字段名:imgUrl,必填") @RequestParam(value = "imgUrl") String imgUrl,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<UserVo> xr = new XaResult<>();
        if (XaUtil.isEmpty(mobile)) {
            xr.error("手机号不能为空!");
            return xr;
        }
        if (XaUtil.isEmpty(payPassword)) {
            xr.error("支付密码不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(code)) {
            xr.error("验证码不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(imgCode)) {
            xr.error("图像验证码不能为空");
            return xr;
        }
        //判断验证码是否正确
        if (!checkCode(request, mobile, code)) {
            xr.error("验证码不正确");
            return xr;
        }

        if (XaUtil.isEmpty(imgCode)) {
            xr.error("图像验证码不能为空！");
            return xr;
        }
        if (imgCode.length() != 4) {
            xr.error("图像验证码格式有误！");
            return xr;
        }
        if (XaUtil.isEmpty(imgUrl)) {
            xr.error("图像路径不能为空！");
            return xr;
        }
        if (!imgUrl.endsWith(".JPEG")) {
            xr.error("图像路径格式不正确！");
            return xr;
        }
        //验证码图像验证码是否正确
        if (!checkImgCode(request, imgCode)) {
            xr.error("图像验证码不正确");
            return xr;
        }
        if (!Validator.isMobile(mobile)) {
            xr.error("手机号码格式不正确");
            return xr;
        }
        User user = userService.validMobile(mobile);
        if (XaUtil.isEmpty(user)) {
            xr.error("手机未注册");
            return xr;
        }
        user.setPayPassword(payPassword);
        return userService.updateModel(user);
    }

    /**
     * @param mobile
     * @return
     * @Title: 忘记交易密码
     * @Description: 忘记交易密码
     */
    @ApiOperation(value = "忘记交易密码", notes = "忘记交易密码,当返回的code=1时，保存成功后object返回对象", position = 4)
    @ResponseBody
    @RequestMapping(value = "payPasswordForget", method = RequestMethod.POST)
    public XaResult<UserVo> payPasswordForget(
            @ApiParam("手机号,字段名:mobile") @RequestParam(value = "mobile") String mobile,
            @ApiParam("验证码,字段名:code") @RequestParam String code,
            @ApiParam("图像验证码,字段名:imgCode,必填") @RequestParam(value = "imgCode") String imgCode,
            @ApiParam("图像路径,字段名:imgUrl,必填") @RequestParam(value = "imgUrl") String imgUrl,
            @ApiParam("新交易密码(login给后台的全是明文密码；pay：给后台的全是md5后的密码),字段名:newPayPassword") @RequestParam String newPayPassword,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<UserVo> xr = new XaResult<UserVo>();
        if (XaUtil.isEmpty(mobile)) {
            xr.error("手机号码不能都为空！");
            return xr;
        }
        if (XaUtil.isNotEmpty(mobile)) {
            if (!Validator.isMobile(mobile)) {
                xr.error("手机号码格式不正确");
                return xr;
            }
        }
        if (XaUtil.isEmpty(code)) {
            xr.error("验证码不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(newPayPassword)) {
            xr.error("新密码不能为空");
            return xr;
        }
        //判断手机验证码是否正确
        if (XaUtil.isNotEmpty(mobile)) {
            if (!checkCode(request, mobile, code)) {
                xr.error("手机验证码不正确");
                return xr;
            }
        }

        if (XaUtil.isEmpty(imgCode)) {
            xr.error("图像验证码不能为空！");
            return xr;
        }
        if (imgCode.length() != 4) {
            xr.error("图像验证码格式有误！");
            return xr;
        }
        if (XaUtil.isEmpty(imgUrl)) {
            xr.error("图像路径不能为空！");
            return xr;
        }
        if (!imgUrl.endsWith(".JPEG")) {
            xr.error("图像路径格式不正确！");
            return xr;
        }
        //验证码图像验证码是否正确
        if (!checkImgCode(request, imgCode)) {
            xr.error("图像验证码不正确");
            return xr;
        }
        return userService.forgetPayPwd(mobile, newPayPassword);
    }


    /**
     * @param mobile
     * @return
     * @Title: sendCode
     * @Description: 发送短信验证码
     */
    @ApiOperation(value = "获取验证码", notes = "查询用户详细信息,当返回的code=1时，取出object进行显示,存放为单体对象", position = 5)
    @ResponseBody
    @RequestMapping(value = "sendCode", method = RequestMethod.POST)
    public XaResult<Map<String, Long>> sendCode(
            @ApiParam("用户Id,字段名:userId,(type=3,4,5)必传，否则不传") @RequestParam(defaultValue = "0", required = false) Long userId,
            @ApiParam("手机号码,字段名:mobile,必填") @RequestParam(value = "mobile") String mobile,
            @ApiParam("手机号码,字段名:DES加密的mobile,必填") @RequestParam(value = "mobileEncrypt") String mobileEncrypt,
            @ApiParam("图像验证码,字段名:imgCode,必填") @RequestParam(value = "imgCode") String imgCode,
            @ApiParam("图像路径,字段名:imgUrl,必填") @RequestParam(value = "imgUrl") String imgUrl,
            @ApiParam("类型,字段名:type(1:注册 2:忘记密码 3:修改手机号码 4:设置交易密码 5:忘记交易密码),必填") @RequestParam(value = "type") int type,
            @ApiParam("类型,字段名:device(1:android 2:ios 3:web) ") @RequestParam(defaultValue = "0", required = false) int device ,
            HttpServletRequest request
    ) throws Exception {
        XaResult<Map<String, Long>> xr = new XaResult<Map<String, Long>>();
        if (XaUtil.isEmpty(mobile)) {
            xr.error("手机号码不能为空");
            return xr;
        }
        if (!Validator.isMobile(mobile)) {
            xr.error("手机号码格式不正确");
            return xr;
        }
        if(device != 3){//APP校验
        	if (XaUtil.isEmpty(mobileEncrypt)) {
        		xr.error("mobileEncrypt不能为空");
        		return xr;
        	}
        	String deMobile = DesUtil.decrypt(mobileEncrypt, DesUtil.DES_KEY);
        	if (!mobile.equals(deMobile)) {
        		xr.error("手机号加密错误！");
        		return xr;
        	}
        }
        if (XaUtil.isEmpty(imgCode)) {
            xr.error("图像验证码不能为空！");
            return xr;
        }
        if (imgCode.length() != 4) {
            xr.error("图像验证码格式有误！");
            return xr;
        }
        if (XaUtil.isEmpty(imgUrl)) {
            xr.error("图像路径不能为空！");
            return xr;
        }
        if (!imgUrl.endsWith(".JPEG")) {
            xr.error("图像路径格式不正确！");
            return xr;
        }
        //验证码图像验证码是否正确
        if (!checkImgCode(request, imgCode)) {
            xr.error("图像验证码不正确");
            return xr;
        } else {
            //验证成功删除图像
            String s = request.getSession().getServletContext().getRealPath("/");
            String fileName = imgUrl.substring(imgUrl.lastIndexOf("/"));
            String rootPath = s.replaceAll("\\\\", "\\\\\\\\") + PATH_IMAGECode;
            File filedict = new File(rootPath + "/" + fileName);
            try {
                jodd.io.FileUtil.delete(filedict);
            } catch (IOException e) {
                System.out.println("图像路径不存在！");
            }
        }
        if (XaUtil.isEmpty(type)) {
            xr.error("type类型不能为空");
            return xr;
        }
        if (type < 1 || type > 5) {
            xr.error("type类型错误,取值范围[1,5]");
            return xr;
        }
        if (!((type == 1 || type == 2))) {
            if (XaUtil.isEmpty(userId)) {
                xr.error("userId不能为空");
                return xr;
            }
        }
        //验证手机号是否注册
        User user = userService.validMobile(mobile);
        if (type != 1) {//不是注册
            if (XaUtil.isEmpty(user)) {
                xr.error("该手机号尚未注册");
                return xr;
            }
        } else {//注册
            if (XaUtil.isNotEmpty(user)) {
                xr.error("该手机号已注册");
                return xr;
            }
        }

        //发送验证码 type(1:注册 2:忘记密码 3:修改手机号码 4:设置交易密码 5:忘记交易密码)
        String actionStr = "注册";
        switch (type) {
            case 1:
                actionStr = "注册";
                break;
            case 2:
                actionStr = "忘记密码";
                break;
            case 3:
                actionStr = "修改手机号码";
                break;
            case 4:
                actionStr = "设置交易密码";
                break;
            case 5:
                actionStr = "忘记交易密码";
                break;
        }

        //随机生成六位验证码
        Map<String, Long> phoneAndCode = new HashMap<String, Long>();
        long code = (long) (Math.random() * 899999) + 100000;
        HashMap<String, Object> result = YuntongxunSmsUtil.sendMessege(mobile, JConstant.ShortMessageType.SM, new String[]{actionStr, code + "", "5"});
        if ("160038".equals((String) result.get("statusCode"))) {
            xr.error("短信验证码发送过频繁，请稍后再试！");
            return xr;
        }
        if ("000000".equals((String) result.get("statusCode"))) {
            //将生成的验证码存到Map集合中返回到前端
            phoneAndCode.put(mobile, code);
            //将生成的验证码保存在session中用来判断验证码是否正确
            HttpSession session = request.getSession();
            session.setAttribute(SESSION_KEY, phoneAndCode);
            session.setMaxInactiveInterval(5 * 60);    //设置有效时间为5分钟
            //if (XaUtil.isNotEmpty(userId)) {
            //    xr.success(phoneAndCode);
            //}
        } else {
            String errorMsg =XaUtil.isEmpty(result.get("statusMsg")) ? null : result.get("statusMsg").toString();
            if (XaUtil.isNotEmpty(errorMsg)) {
                xr.error(errorMsg);
            } else  {
                xr.error("验证码发送失败，请稍后再试");
            }
            logger.error("云通讯statusCode:" + result.get("statusCode" + "(" + result.get("statusMsg") + ")"), new Throwable("云通讯验证码发送失败"));
        }
        return xr;
    }

    /**
     * @return
     * @Title:
     * @Description: 修改一条实体
     */
    @ApiOperation(value = "修改资料", notes = "修改用户,当返回的code=1时，保存成功后object返回对象")
    @ResponseBody
    @RequestMapping(value = "updateUser", method = RequestMethod.POST)
    public XaResult<UserVo> updateUser(
            @ApiParam("用户id,字段名:id") @RequestParam(value = "userId") Long userId,
            @ApiParam("用户名,字段名:userName") @RequestParam(value = "userName", required = false) String userName,
            @ApiParam("头像,字段名:photo") @RequestParam(value = "photo", required = false) String photo,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<UserVo> xr = new XaResult<>();
        if (XaUtil.isEmpty(userId)) {
            xr.error("userId不能为空");
            return xr;
        }
        User model = new User();
        model.setUserName(userName);
        model.setPhoto(photo);
        model.setId(userId);
        return userService.updateModel(model);
    }

    /**
     * @return
     * @Title:
     * @Description: 修改手机号
     */
    @ApiOperation(value = "修改手机号", notes = "修改用户,当返回的code=1时，保存成功后object返回对象")
    @ResponseBody
    @RequestMapping(value = "updateUserMobile", method = RequestMethod.POST)
    public XaResult<UserVo> updateUserMobile(
            @ApiParam("用户id,字段名:id") @RequestParam(value = "userId") Long userId,
            @ApiParam("验证码,字段名:code") @RequestParam String code,
            @ApiParam("用户名,字段名:newMoble") @RequestParam(value = "newMoble") String newMoble,
            @ApiParam("图像验证码,字段名:imgCode,必填") @RequestParam(value = "imgCode") String imgCode,
            @ApiParam("图像路径,字段名:imgUrl,必填") @RequestParam(value = "imgUrl") String imgUrl,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<UserVo> xr = new XaResult<>();
        if (XaUtil.isEmpty(userId)) {
            xr.error("userId不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(code)) {
            xr.error("验证码不能为空");
            return xr;
        }
        if (XaUtil.isEmpty(newMoble)) {
            xr.error("手机号码不能为空");
            return xr;
        }
        if (!Validator.isMobile(newMoble)) {
            xr.error("手机号码格式不正确");
            return xr;
        }
        //验证手机号是否注册
        User user = userService.validMobile(newMoble);
        if (XaUtil.isNotEmpty(user)) {
            xr.error("该手机号已被绑定");
            return xr;
        }
        xr = userService.findOne(userId);
        //判断验证码是否正确
        if (!checkCode(request, xr.getObject().getMobile(), code)) {//老手机
            xr.error("验证码不正确");
            return xr;
        }

        if (XaUtil.isEmpty(imgCode)) {
            xr.error("图像验证码不能为空！");
            return xr;
        }
        if (imgCode.length() != 4) {
            xr.error("图像验证码格式有误！");
            return xr;
        }
        if (XaUtil.isEmpty(imgUrl)) {
            xr.error("图像路径不能为空！");
            return xr;
        }
        if (!imgUrl.endsWith(".JPEG")) {
            xr.error("图像路径格式不正确！");
            return xr;
        }
        //验证码图像验证码是否正确
        if (!checkImgCode(request, imgCode)) {
            xr.error("图像验证码不正确");
            return xr;
        }

        User model = new User();
        model.setId(userId);
        model.setMobile(newMoble);
        return userService.updateModel(model);
    }

    /**
     * @param id
     * @return
     * @Title: findUserDetail
     * @Description: 用户详情
     */
    @ApiOperation(value = "用户详情", notes = "查询用户详细信息,当返回的code=1时，取出object进行显示,存放为单体对象")
    @ResponseBody
    @RequestMapping(value = "findUserDetail", method = RequestMethod.POST)
    public XaResult<UserVo> findUserById(
            @ApiParam("编号,字段名:id,必填") @RequestParam(value = "id") Long id
    ) throws BusinessException {
        XaResult<UserVo> xr = new XaResult<UserVo>();
        if (XaUtil.isEmpty(id)) {
            xr.error("id不能为空");
            return xr;
        }
        return userService.findOne(id);
    }

    /**
     * 获取验证码
     */
    @ApiOperation(value = "获取图形验证码", notes = "获取图形验证码,当返回的code=1时，返回图形验证码和手机号")
    @ResponseBody
    @RequestMapping(value = "getValiCode", method = RequestMethod.POST)
    public XaResult<String> getValiCode(
            HttpServletRequest request,
            HttpServletResponse response
    ) {
        XaResult<String> xr = new XaResult<String>();
        try {
            Map<String, BufferedImage> map = ImageUtil.createImage();
            String code = map.keySet().iterator().next();
            BufferedImage image = map.get(code);
            HttpSession session = request.getSession();
            session.setAttribute(SESSION_IMAGE_KEY, code);
            session.setMaxInactiveInterval(5 * 60);    //设置有效时间为5分钟
            String s = request.getSession().getServletContext().getRealPath("/");
            String fileName = new Date().getTime() + ".JPEG";
            String rootPath = s.replaceAll("\\\\", "\\\\\\\\") + PATH_IMAGECode;
            File filedict = new File(rootPath + "/" + fileName);
            if (!filedict.exists()) {
                filedict.mkdirs();
            }
            ImageIO.write(image, "JPEG", filedict);
            String base_url = "/upload/graphValidateCode/" + fileName;
            xr.success(base_url);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return xr;
    }

    /**
     * @param photoFile
     * @param request
     * @return
     * @Title: upload
     * @Description: 图片上传
     */
    @ApiOperation(value = "图片上传", notes = "异步图片上传,返回上传图片的地址、宽、高")
    @ResponseBody
    @RequestMapping(value = "photoUpload", method = RequestMethod.POST)
    public XaResult<Map<String, Object>> photoUpload(
            @ApiParam("上传的图片,字段名:photoFile,必填") @RequestParam(value = "photoFile") MultipartFile photoFile,
            @ApiParam("type,字段名:类别(1:个人图像; 2:意见反馈; 3:评论 4:朋友圈 5:加盟申请单 6:义工中心 7:申请退款 8:后续添加..),必填") @RequestParam(value = "type") int type,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<Map<String, Object>> result = new XaResult<Map<String, Object>>();
        String root = request.getSession().getServletContext().getRealPath("/");
        String picturePath = "";
        if (type == 1) {
            picturePath = "/upload/user";
        } else if (type == 2) {
            picturePath = "/upload/feedBack";
        } else if (type == 3) {
            picturePath = "/upload/comment";
        } else if (type == 4) {
            picturePath = "/upload/momments";
        } else if (type == 5) {
            picturePath = "/upload/franchise";
        } else if (type == 6) {
            picturePath = "/upload/vsdc";
        } else if (type == 7) {
            picturePath = "/upload/refundHavePwd";
        } else {
            picturePath = "/upload/other";
        }
        String ext = photoFile.getOriginalFilename().substring(photoFile.getOriginalFilename().lastIndexOf("."));
        String newName = new Date().getTime() + ext;
        File filedict = new File(root + picturePath);
        if (!filedict.exists()) {
            filedict.mkdirs();
        }
        File targetFile = new File(root + picturePath + File.separator + newName);
        try {
            if (StringUtils.equalsIgnoreCase(ext, ".jpg") || StringUtils.equalsIgnoreCase(ext, ".png")) {
                photoFile.transferTo(targetFile);
                BufferedImage bimg = ImageIO.read(targetFile);
                int width = bimg.getWidth();
                int height = bimg.getHeight();
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("pictureHeight", height);
                map.put("pictureWidth", width);
                map.put("picturePath", picturePath + "/" + newName);
                result.setObject(map);
                return result;
            } else {
                throw new BusinessException("上传文件类型不允许,请上传jpg/png图片");
            }
        } catch (IllegalStateException e) {
            throw new BusinessException("图片上传失败");
        } catch (IOException e) {
            throw new BusinessException("图片上传失败(IO)");
        } catch (Exception e) {
            throw new BusinessException("图片上传失败(Ex)");
        }
    }

    @ApiOperation(value = "根据推荐人手机号查询用户（1,2级）", notes = "根据推荐人手机号查询用户（1,2级）,当返回的code=1时，注册成功后object返回对象", position = 1)
    @ResponseBody
    @RequestMapping(value = "findUserList", method = RequestMethod.POST)
    public XaResult<List<UserVo>> findUserList(
            @ApiParam("推荐人手机号,字段名:recommendPhone") @RequestParam(value = "recommendPhone") String recommendPhone
    ) {
        XaResult<List<UserVo>> xr = new XaResult<List<UserVo>>();
        try {
            return userService.findUserList(recommendPhone);
        } catch (Exception e) {
            if (e instanceof BusinessException) {
                xr.error(e.getMessage());
            } else {
                xr.error(XaConstant.Message.error);
            }
        }
        return xr;
    }

    /**
     * 检查验证码是否正确
     *
     * @param request
     * @param phone
     * @param code
     * @return
     */
    @SuppressWarnings({"unchecked"})
    private boolean checkCode(HttpServletRequest request, String phone, String code) {
        HashMap<String, Long> phoneAndCode = (HashMap<String, Long>) request.getSession().getAttribute(SESSION_KEY);
        if (XaUtil.isEmpty(phoneAndCode)) {
            return false;
        }
        return phoneAndCode.containsKey(phone) && phoneAndCode.containsValue(Long.valueOf(code));
    }

    /**
     * 检查图像验证码是否正确
     *
     * @param request
     * @param code
     * @return
     */
    private boolean checkImgCode(HttpServletRequest request, String code) {
        String phoneAndCode = (String) request.getSession().getAttribute(SESSION_IMAGE_KEY);
        if (XaUtil.isEmpty(phoneAndCode)) {
            return false;
        }
        return phoneAndCode.equalsIgnoreCase(code.trim());
    }

    /**
     * 获取登录的ip
     *
     * @param request
     * @return
     */
    private String getRemortIP(HttpServletRequest request) {
        if (request.getHeader("x-forwarded-for") == null) {
            return request.getRemoteAddr();
        }
        return request.getHeader("x-forwarded-for");
    }
}

